#include "hf_hal_iic.h"

// 私有函数：等待I2C事件
static int8_t hf_iic_wait_event(uint32_t event)
{
    uint32_t timeout = I2C_TIMEOUT;
    while (!I2C_CheckEvent(I2C_PORT, event)) {
        if (--timeout == 0) {
            return I2C_TIMEOUT_ERROR;
        }
    }
    return I2C_OK;
}

int8_t hf_iic_init(void)
{
    I2C_InitTypeDef I2C_InitStruct;
    GPIO_InitTypeDef GPIO_InitStruct;

    // 使能I2C和GPIO时钟
    RCC_APB1PeriphClockCmd(I2C_RCC_PERIPH, ENABLE);
    RCC_AHB1PeriphClockCmd(I2C_RCC_GPIO, ENABLE);

    // 配置GPIO引脚（SCL和SDA）
    GPIO_InitStruct.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; // 开漏输出
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;   // 上拉
    GPIO_Init(I2C_GPIO_PORT, &GPIO_InitStruct);

    // 引脚复用映射到I2C
    GPIO_PinAFConfig(I2C_GPIO_PORT, GPIO_PinSource6, GPIO_AF_I2C1); // PB6 -> SCL
    GPIO_PinAFConfig(I2C_GPIO_PORT, GPIO_PinSource7, GPIO_AF_I2C1); // PB7 -> SDA

    // 配置I2C
    I2C_InitStruct.I2C_ClockSpeed = I2C_SPEED;
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStruct.I2C_OwnAddress1 = 0x00; // 主模式不需要
    I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C_PORT, &I2C_InitStruct);

    // 使能I2C
    I2C_Cmd(I2C_PORT, ENABLE);
}

int8_t hf_iic_write(uint8_t slave_addr, uint8_t *p_data, uint16_t size)
{
    // 生成起始条件
    I2C_GenerateSTART(I2C_PORT, ENABLE);
    if (hf_iic_wait_event(I2C_EVENT_MASTER_MODE_SELECT) != I2C_OK) return I2C_TIMEOUT_ERROR;

    // 发送从设备地址（写）
    I2C_Send7bitAddress(I2C_PORT, slave_addr, I2C_Direction_Transmitter);
    if (hf_iic_wait_event(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != I2C_OK) return I2C_TIMEOUT_ERROR;

    // 发送数据
    for (uint16_t i = 0; i < size; i++) {
        I2C_SendData(I2C_PORT, p_data[i]);
        if (hf_iic_wait_event(I2C_EVENT_MASTER_BYTE_TRANSMITTED) != I2C_OK) return I2C_TIMEOUT_ERROR;
    }

    // 生成停止条件
    I2C_GenerateSTOP(I2C_PORT, ENABLE);
    return I2C_OK;
}

int8_t hf_iic_read(uint8_t slave_addr, uint8_t *p_data, uint16_t size)
{
    // 生成起始条件
    I2C_GenerateSTART(I2C_PORT, ENABLE);
    if (hf_iic_wait_event(I2C_EVENT_MASTER_MODE_SELECT) != I2C_OK) return I2C_TIMEOUT_ERROR;

    // 发送从设备地址（读）
    I2C_Send7bitAddress(I2C_PORT, slave_addr, I2C_Direction_Receiver);
    if (hf_iic_wait_event(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != I2C_OK) return I2C_TIMEOUT_ERROR;

    // 接收数据
    for (uint16_t i = 0; i < size; i++) {
        if (i == size - 1) {
            I2C_AcknowledgeConfig(I2C_PORT, DISABLE); // 最后一个字节禁用ACK
        }
        if (hf_iic_wait_event(I2C_EVENT_MASTER_BYTE_RECEIVED) != I2C_OK) return I2C_TIMEOUT_ERROR;
        p_data[i] = I2C_ReceiveData(I2C_PORT);
    }

    // 恢复ACK并生成停止条件
    I2C_AcknowledgeConfig(I2C_PORT, ENABLE);
    I2C_GenerateSTOP(I2C_PORT, ENABLE);
    return I2C_OK;
}

uint8_t hf_iic_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *p_data, uint16_t size)
{
    // 先发送寄存器地址
    uint8_t status = hf_iic_write(slave_addr, &reg_addr, 1);
    if (status != I2C_OK) return status;

    // 再发送数据
    return hf_iic_write(slave_addr, p_data, size);
}

uint8_t hf_iic_read_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t *p_data, uint16_t size)
{
    // 先发送寄存器地址
    int8_t status = hf_iic_write(slave_addr, &reg_addr, 1);
    if (status != I2C_OK) return status;

    // 再读取数据
    return hf_iic_read(slave_addr, p_data, size);
}